﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace Xceed.Silverlight.Data
{
  internal sealed class DataRangeContext : IEquatable<DataRangeContext>
  {
    #region Constructor

    internal DataRangeContext(
      Type userObjectType,
      IEnumerable<SortDescription> sortDescriptions,
      Predicate<object> filter,
      FilterExpressionBase filterExpression )
    {
      if( userObjectType == null )
        throw new ArgumentNullException( "userObjectType" );

      m_userObjectType = userObjectType;

      if( sortDescriptions == null )
        throw new ArgumentNullException( "sortDescriptions" );

      m_sortDescriptions = new ReadOnlyCollection<SortDescription>( sortDescriptions.ToList() );

      if( m_sortDescriptions.Count <= 0 )
        throw new ArgumentException( "sortDescriptions must have at least one item.", "sortDescriptions" );

      m_filter = filter;
      m_filterExpression = filterExpression;
    }

    #endregion

    #region UserObjectType Property

    internal Type UserObjectType
    {
      get
      {
        return m_userObjectType;
      }
    }

    private readonly Type m_userObjectType; //null

    #endregion UserObjectType Property

    #region SortDescriptions Property

    internal IList<SortDescription> SortDescriptions
    {
      get
      {
        return m_sortDescriptions;
      }
    }

    private readonly IList<SortDescription> m_sortDescriptions; //null

    #endregion SortDescriptions Property

    #region Filter Property

    internal Predicate<object> Filter
    {
      get
      {
        return m_filter;
      }
    }

    private readonly Predicate<object> m_filter; //null

    #endregion Filter Property

    #region FilterExpression Property

    internal FilterExpressionBase FilterExpression
    {
      get
      {
        return m_filterExpression;
      }
    }

    private readonly FilterExpressionBase m_filterExpression; //null

    #endregion FilterExpression Property

    public override int GetHashCode()
    {
      int hashCode = 17;

      hashCode ^= DataRangeContext.ComputeHashCode( this.UserObjectType );
      hashCode ^= DataRangeContext.ComputeHashCode( this.FilterExpression );

      return hashCode;
    }

    public override bool Equals( object obj )
    {
      return this.Equals( obj as DataRangeContext );
    }

    public bool Equals( DataRangeContext obj )
    {
      if( obj == null )
        return false;

      if( obj == this )
        return true;

      return ( object.Equals( this.UserObjectType, obj.UserObjectType ) )
          && ( object.Equals( this.Filter, obj.Filter ) )
          && ( object.Equals( this.FilterExpression, obj.FilterExpression ) )
          && ( this.SortDescriptions.SequenceEqual( obj.SortDescriptions ) );
    }

    private static int ComputeHashCode( object obj )
    {
      if( obj == null )
        return 0;

      return obj.GetHashCode();
    }
  }
}
